import pandas as pd
import glob, folium, branca, json
import numpy as np
import matplotlib.pyplot as plt
import holoviews as hv
import panel as pn
import panel.widgets as pnw
hv.extension('bokeh')
from bokeh.themes.theme import Theme
theme = Theme(
json={
'attrs' : {
'Figure' : {
'background_fill_color': '#535353',
'border_fill_color': '#535353',
'outline_line_color': '#444444',
},
'Grid': {
'grid_line_dash': [6, 4],
'grid_line_alpha': .3,
},
'Axis': {
'major_label_text_color': 'white',
'axis_label_text_color': 'white',
'major_tick_line_color': 'white',
'minor_tick_line_color': 'white',
'axis_line_color': "white"
}
}
})
hv.renderer('bokeh').theme = theme
print(np.datetime64('now'))
2021-02-27T00:50:16
# PUT EVERY COUNTRY REPORTS IN ONE DATAFRAME
files = glob.glob('data/install*country.csv')
files.sort()
ds=pd.DataFrame()
for f in files:
ds = pd.concat([ds,pd.read_csv(f,encoding = 'utf-16')])
ds = ds.reset_index()
ds = ds.drop(columns=['index','Daily Device Upgrades','Total User Installs','Active Device Installs','Install events','Update events','Uninstall events'])
ds['Date']=pd.DatetimeIndex(ds['Date'])
ds['WO-ui']=ds['Daily User Installs'].cumsum()
ds['WO-di']=ds['Daily Device Installs'].cumsum()
ds['WO-uu']=ds['Daily User Uninstalls'].cumsum()
ds['WO-du']=ds['Daily Device Uninstalls'].cumsum()
countries = np.unique(ds['Country'][~ds['Country'].isna()])
for country in np.unique(ds['Country'][~ds['Country'].isna()]):
ds[country+'-di']=ds[ds['Country']==country]['Daily Device Installs'].cumsum()
ds[country+'-ui']=ds[ds['Country']==country]['Daily User Installs'].cumsum()
ds[country+'-du']=ds[ds['Country']==country]['Daily Device Uninstalls'].cumsum()
ds[country+'-uu']=ds[ds['Country']==country]['Daily User Uninstalls'].cumsum()
ds = ds.fillna(method='ffill')
ds = ds.fillna(0)
ds.tail()
| Date | Package Name | Country | Daily Device Installs | Daily Device Uninstalls | Daily User Installs | Daily User Uninstalls | WO-ui | WO-di | WO-uu | ... | SV-du | SV-uu | UA-di | UA-ui | UA-du | UA-uu | US-di | US-ui | US-du | US-uu | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1188 | 2021-02-23 | com.kb.android.argo | MY | 0 | 0 | 0 | 0 | 82 | 86 | 29 | ... | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 1.0 | 7.0 | 5.0 | 0.0 | 1.0 |
| 1189 | 2021-02-23 | com.kb.android.argo | NO | 0 | 0 | 0 | 0 | 82 | 86 | 29 | ... | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 1.0 | 7.0 | 5.0 | 0.0 | 1.0 |
| 1190 | 2021-02-23 | com.kb.android.argo | RU | 0 | 0 | 0 | 0 | 82 | 86 | 29 | ... | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 1.0 | 7.0 | 5.0 | 0.0 | 1.0 |
| 1191 | 2021-02-23 | com.kb.android.argo | SI | 0 | 0 | 0 | 0 | 82 | 86 | 29 | ... | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 1.0 | 7.0 | 5.0 | 0.0 | 1.0 |
| 1192 | 2021-02-23 | com.kb.android.argo | US | 0 | 0 | 0 | 0 | 82 | 86 | 29 | ... | 0.0 | 1.0 | 1.0 | 1.0 | 0.0 | 1.0 | 7.0 | 5.0 | 0.0 | 1.0 |
5 rows × 131 columns
A2 = pd.read_csv('A2codes.csv',index_col=1)
A2i = pd.read_csv('A2codes.csv',index_col=0)
labels = sorted([A2['Name'][x] for x in np.hstack([countries,'WO'])])
label = pnw.Select(name='Country', value='World', options=labels)
ptype = pnw.Select(name='Type', value='Install', options=['Install','Uninstall'])
@pn.depends(label.param.value,ptype.param.value)
def create_figure(label,ptype):
code = A2i['Code'][label]
if code != 'WO':
dsi = ds[ds['Country']==code]
else:
dsi=ds
hv_data = hv.Table(dsi, ['Date'])
p1 = hv_data.to.curve(['Date'], [code+'-u'+ptype[0].lower()],label='Users').opts(color='#2acaea')
p2 = hv_data.to.curve(['Date'], [code+'-d'+ptype[0].lower()],label='Devices').opts(color='#d71e3e')
p = p1*p2
p.opts(hv.opts.Curve(width=700, height=400,show_grid=True),
hv.opts.Overlay(legend_position='top_left'))
return p
#Panel dataframe looks better than holoview's
@pn.depends(label.param.value,ptype.param.value)
def create_table(label,ptype):
code = A2i['Code'][label]
if code != 'WO':
dsi = ds[ds['Country']==code]
else:
dsi=ds
return pnw.DataFrame(dsi[['Date',code+'-u'+ptype[0].lower(),code+'-d'+ptype[0].lower()]].groupby('Date').max(),height=400, widths=180, autosize_mode='none')
widgets = pn.WidgetBox(label, ptype, width=170)
pn.Row(widgets, create_figure, create_table)
df = pd.DataFrame(ds.groupby('Country').sum()['Daily User Installs'])
color_scale = branca.colormap.linear.viridis.scale(0,20)
map_dict = df.to_dict()
def get_color(feature):
value = map_dict['Daily User Installs'].get(feature['properties']['ISO_A2'])
if value is None:
return 'white' # MISSING -> white
else:
#print(feature['properties']['ADMIN']+' : '+str(value))
return color_scale(value)
m = folium.Map(
location = [0, 0],
tiles="cartodbpositron",
zoom_start = 2
)
folium.GeoJson(
data = 'countries.json',
style_function = lambda feature: {
'fillColor': get_color(feature),
'fillOpacity': 0.7,
'color' : 'None',
'weight' : 1,
}
).add_to(m)
m.add_child(color_scale)
m